﻿using System;
using System.Collections.Generic;
using System.Linq;
using Occt;

namespace Tx.OCC
{
    /// <summary>
    /// The occ td f ex.
    /// </summary>
    public static class OccTdFEx
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="label"></param>
        /// <returns></returns>
        public static string Name(this TDF_Label label)
        {
            var name = "";
            if (label == null || label.IsNull)
                return name;

            if (label.FindAttribute(TDataStd_Name.ID, out var attribute))
                name = (attribute as TDataStd_Name).Value.ToString();
            return name;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="label"></param>
        /// <returns></returns>
        public static string LabelName(this TDF_Label label)
        {
            string name = "";
            if (label == null || label.IsNull)
                return name;
            if (!XCAFDoc_ShapeTool.IsReference(label))
                return label.Name();
            //             if (!options.useBaseName)
            //                 name = label.LabelName();
            if (name.IsNullOrEmpty() && XCAFDoc_ShapeTool.GetReferredShape(label, out var refLabel))
                name = refLabel.Name();
            return name;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="label"></param>
        /// <returns></returns>
        public static IEnumerable<TDF_Label> Children(this TDF_Label label)
        {
            for (var itr = new TDF_ChildIterator(label); itr.More; itr.Next())
            {
                yield return itr.Value;
            }
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="label">The label.</param>
        /// <returns>IEnumerable&lt;Value&lt;System.String, T&gt;&gt;.</returns>
        public static IEnumerable<Tuple<string, T>> AnalyzeLabel<T>(this TDF_Label label) where T : TopoDS_Shape
        {
            var type = TDataStd_Name.ID;
            if (label.HasChild)
            {
                for (int i = 0; i < label.NbChildren; i++)
                {
                    var child = label.FindChild(i);
                    foreach (var value in child.AnalyzeLabel<T>())
                    {
                        yield return value;
                    }
                }
            }
            else if (XCAFDoc_ShapeTool.IsShape(label))
            {
                var shape = XCAFDoc_ShapeTool.GetShape(label);
                var name = string.Empty;
                if (label.FindAttribute(type, out TDF_Attribute anAttribute))
                    name = (anAttribute as TDataStd_Name).Value.ToString();

                if (shape is T)
                {
                    yield return new Tuple<string, T>(name, shape as T);
                }
                else if (shape is TopoDS_Compound)
                {
                    var compound = shape as TopoDS_Compound;
                    int index = 0;
                    foreach (var shape1 in compound.Explorer<T>())
                    {
                        yield return new Tuple<string, T>(name + "-" + index, shape1 as T);
                    }
                }
            }
        }
    }
}
